/**
 * @file extract.cpp
 * Copyright (c) 2020 Gaaagaa. All rights reserved.
 * 
 * @author  : Gaaagaa
 * @date    : 2020-12-30
 * @version : 1.0.0.0
 * @brief   : 测试 PDFium 库 ：提取 PDF 页面到 JPEG 图片。
 */

#include "xtypes.h"
#include "XJPEG_wrapper.h"
#include "XPDF_wrapper.h"

////////////////////////////////////////////////////////////////////////////////
// for mkdir()

#if (defined(_WIN32) || defined(_WIN64))
#include <direct.h>
#elif defined(__linux__) // linux
#include <sys/stat.h>
#include <sys/types.h>
#else // unknow
#error "The current platform is not supported"
#endif // (defined(_WIN32) || defined(_WIN64))

x_int32_t X_mkdir(x_cstring_t xszt_path, x_uint32_t xut_mode)
{
#if (defined(_WIN32) || defined(_WIN64))
    if (0 != _mkdir(xszt_path))
#elif defined(__linux__) // linux
    if (0 != mkdir(xszt_path, xut_mode))
#else // unknow
#error "The current platform is not supported"
#endif // (defined(_WIN32) || defined(_WIN64))
    {
        if (EEXIST != errno)
            return -1;
    }

    return 0;
}

////////////////////////////////////////////////////////////////////////////////

x_cstring_t file_ext_name(x_cstring_t xszt_fpath, x_bool_t xbt_with_dot)
{
    x_char_t * xct_iter = (x_char_t *)xszt_fpath;
    x_char_t * xct_vpos = X_NULL;

    if (X_NULL == xszt_fpath)
    {
        return X_NULL;
    }
    else if ('.' == xszt_fpath[0])
    {
        // "." or ".." will return to tail.
        if ('\0' == xszt_fpath[1])
            return xszt_fpath + 1;
        else if (('.' == xszt_fpath[1]) && ('\0' == xszt_fpath[2]))
            return xszt_fpath + 2;
    }

    while (*xct_iter)
    {
        if ('.' == *xct_iter)
            xct_vpos = xct_iter + 1;
        xct_iter += 1;
    }

    if (X_NULL == xct_vpos)
        xct_vpos = xct_iter;
    else if (xbt_with_dot)
        xct_vpos -= 1;

    return (x_cstring_t)xct_vpos;
}

////////////////////////////////////////////////////////////////////////////////

int main(int argc, char * argv[])
{
    x_int32_t xit_err = X_ERR_UNKNOW;

    //======================================

    if (argc < 2)
    {
        printf("usage:                                                            \n"
               " %s < input > [zoom : 1.0]                                        \n"
               "     input : PDF file .                                           \n"
               "     zoom  : The zoom ratio of the output image size, float type .\n",
               argv[0]);
        return -1;
    }

    std::string xstr_file = argv[1];
    x_lfloat_t  xlft_zoom = 1.0;
    if (argc >= 3)
    {
        xlft_zoom = std::atof(argv[2]);
        if (std::abs(xlft_zoom - 0.01) < 1.0e-6)
        {
            xlft_zoom = 1.0;
        }
    }

    //======================================

    if (0 != XPDF_load("pdfium.dll", X_NULL))
    {
        printf("XPDF_load() failed!\n");
        return -1;
    }

    //======================================

    x_errno_t xerr_no = X_ERR_UNKNOW;

    x_uint32_t xut_cx    = 0;
    x_uint32_t xut_cy    = 0;
    x_pvoid_t  xbits_ptr = X_NULL;
    x_int32_t  xit_pitch = 0;

    do
    {
        //======================================

        std::string xstr_path((x_cstring_t)argv[1], file_ext_name(argv[1], X_TRUE));
        xstr_path.append(1, '/');

        if (0 != X_mkdir(xstr_path.c_str(), 0755))
        {
            printf("X_mkdir([%s], 0755) failed!", xstr_path.c_str());
            break;
        }

        x_char_t   xszt_path[TEXT_LEN_512] = { 0 };
        x_char_t * xszt_name = xszt_path + sprintf(xszt_path, "%s", xstr_path.c_str());

        //======================================

        XPDF_reader_t xpdf_reader;

        xerr_no = xpdf_reader.open(xstr_file.c_str(), X_NULL);
        if (XERR_FAILED(xerr_no))
        {
            printf("xpdf_reader.open([%s], X_NULL) return error : %s\n",
                   xstr_file.c_str(),
                   XPDF_reader_t::xerrno_name(xerr_no));
            break;
        }

        //======================================

        jenc_handle_t jencoder;

        for (x_int32_t xit_iter = 0; xit_iter < xpdf_reader.get_page_count(); ++xit_iter)
        {
            sprintf(const_cast< x_char_t * >(xszt_name), "%08d.jpg", xit_iter + 1);

            //======================================

            xut_cx    = 0;
            xut_cy    = 0;
            xbits_ptr = X_NULL;
            xit_pitch = 0;

            xerr_no = xpdf_reader.render_page(
                                        xit_iter,
                                        (x_float_t)xlft_zoom,
                                        xut_cx,
                                        xut_cy,
                                        xbits_ptr,
                                        xit_pitch);
            if (XERR_FAILED(xerr_no))
            {
                printf("xpdf_reader.render_page([%d], ...) return error : %s\n",
                       xit_iter + 1,
                       XPDF_reader_t::xerrno_name(xerr_no));
                break;
            }

            //======================================

            jencoder.config_dst(JCTRL_MODE_FILE, (j_handle_t)xszt_path, 0);
            xit_err = jencoder.rgb_to_dst(
                                        (j_mem_t)xbits_ptr,
                                        xit_pitch,
                                        (j_int_t)xut_cx,
                                        (j_int_t)xut_cy,
                                        JCTRL_CS_BGRA);
            if (JENC_ERR_OK != xit_err)
            {
                printf("[image: %s] jencoder.rgb_to_dst(...) return error : %s\n",
                       xszt_path,
                       jenc_errno_name(xit_err));
                break;
            }

            printf("output jpeg file: %s\n", xszt_path);

            //======================================
        }

        //======================================
    } while (0);

    //======================================

    XPDF_unload();

    //======================================

    return xit_err;
}

////////////////////////////////////////////////////////////////////////////////
